#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/module.h>


#define chardevbase_major   200
#define chardevbase_name    "chardevbase"

static char writebuf[100];
static char readbuf[100];

static char writedata[] = {"hello linux"};

int chardevbase_open (struct inode *nd, struct file *fp)
{
    return 0;
}

ssize_t chardevbase_write (struct file *fp, const char __user *buf, size_t len, loff_t *offset)
{
    int retval = 0;

    retval = copy_from_user(writebuf,buf,len);

    if (retval == 0)
    {
        printk("kernel recv data:%s\r\n",writebuf);
    }
    else
    {
        printk("kernel recv data error\r\n");
    }

    return 0;
}

ssize_t chardevbase_read (struct file *fp, char __user *buf, size_t len, loff_t *offset)
{
    int retval = 0;

    memcpy(readbuf,writedata,sizeof(writedata));

    retval = copy_to_user(buf,readbuf,len);

    if (retval == 0)
    {
        printk("kernel senddata ok\r\n");
    }
    else
    {
        printk("kernel senddata failed\r\n");
    }
    

    return 0;
}

int chardevbase_release (struct inode *nd, struct file *fp)
{

    return 0;
}

static struct file_operations chardevbase_fops = 
{
    .owner = THIS_MODULE,
    .open = chardevbase_open,
    .write = chardevbase_write,
    .read = chardevbase_read,
    .release = chardevbase_release,
};


static int __init chardevbase_init(void)
{
    int retval = 0;

    retval = register_chrdev(chardevbase_major,chardevbase_name,&chardevbase_fops);
    if (retval < 0)
    {
        printk("chardevbase register init failed\r\n");
    }

    printk("chardevbase init()\r\n");
    

    return 0;
}

static void __exit chardevbase_exit(void)
{
    unregister_chrdev(chardevbase_major,chardevbase_name);
    printk("chardevbase exit()\r\n");
}


module_init(chardevbase_init);
module_exit(chardevbase_exit);


MODULE_LICENSE("GPL");
MODULE_AUTHOR("Lux");